package com.spring.pay.alipay.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.spring.common.allocation.BaseDataInitialize;
import com.spring.common.redis.JedisManager;
import com.spring.pay.alipay.config.AlipayConfig;
import com.spring.pay.alipay.service.IAlipayService;
import com.spring.pay.alipay.util.AlipayNotify;
import com.spring.pay.alipay.vo.AlipayRefundBizContent;
import com.spring.trade.po.TradeOrderInfo;
import com.spring.trade.service.ITradeOrderInfoService;
import com.spring.util.IdentityHelper;
import com.spring.util.TradeOrderInfoStatus;
import com.spring.util.constant.Constant;

@Service
public class AlipayServiceImpl implements IAlipayService {
	private Logger LOGGER = Logger.getLogger(AlipayServiceImpl.class);
	@Autowired
	private ITradeOrderInfoService tradeOrderInfoServiceImpl;

/*	@Autowired
	private ITradeCashInfoService tradeCashInfoService;
	@Autowired
	private IDocDoctorInfoService doctorInfoService;
	
	@Autowired
	private ITradeServiceInfoService tradeServiceInfoService;
	@Autowired
	private IPatientCustomerService patientCustomerService;
	@Autowired
	private IPatientBuyCallService patientBuyCallService;*/
	



	@Override
	public String receiveNotify(Map<String, String[]> requestMap) {
		try {
			Map<String, String> params = new HashMap<String, String>();
			for (Iterator iter = requestMap.keySet().iterator(); iter.hasNext();) {
				String name = (String) iter.next();
				String[] values = (String[]) requestMap.get(name);
				String valueStr = "";
				for (int i = 0; i < values.length; i++) {
					valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
				}
				// 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
				// valueStr = new
				// String(valueStr.getBytes("ISO-8859-1"),"UTF-8");
				params.put(name, valueStr);
			}
			String signContent = AlipaySignature.getSignContent(params);
			LOGGER.debug("请求参数排序后：" + signContent);

			boolean check = AlipaySignature.rsaCheckV1(params, AlipayConfig.PUBLIC_KEY, AlipayConfig.CHARSET);
			if (!check) {
				LOGGER.debug("支付宝回调签名校验失败！");
				return "faild";
			}

			LOGGER.debug("支付宝回调签名校验成功！");
			// 4验证app_id是否为该商户本身
			if (!AlipayConfig.APP_ID.equals(params.get("app_id"))) {
				LOGGER.debug("支付宝回调APIID校验失败！");
				return "faild";
			}

			// 3、校验通知中的seller_id（或者seller_email)是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email）

			// 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号
			TradeOrderInfo info = tradeOrderInfoServiceImpl.selectByorderNo(params.get("out_trade_no")); // out_trade_no
			if (info == null) {
				LOGGER.debug("支付宝回调out_trade_no校验失败！");
				return "faild";
			}

			if (StringUtils.isNotBlank(info.getPayOrderNo())) {
				LOGGER.debug("支付宝回调通知已处理过！");
				return "faild";
			}
			if (info.getOrderMoney().compareTo(new BigDecimal(params.get("total_amount"))) != 0) {
				LOGGER.debug("支付宝回调订单金额校验失败！");
				return "faild";
			}
			// 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额）

			info.setPayOrderNo(params.get("trade_no")); // trade_no
			info.setPayTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(params.get("gmt_payment")));
			info.setStatus(TradeOrderInfoStatus.ORDER_PAY.getValue()); // 1 已支付
			info.setPayType(Constant.alipay);
			tradeOrderInfoServiceImpl.updateByPrimaryKeySelective(info);
			JedisManager.setObject(info.getOrderNo(), 0, TradeOrderInfoStatus.ORDER_PAY.getValue());
			LOGGER.debug("支付宝回调处理成功！");
/*			DocDoctorInfo doctorInfo = doctorInfoService.selectDocDoctorInfoKey(info.getDoctorId());
			PatientCustomer patientCustomer = patientCustomerService.selectByPrimaryKey(info.getPatientId());*/
			Integer hourNum = BaseDataInitialize.getMsgCount(1, Constant.IMAGE_TEXT_RULE_HOUR_CODE);
			Integer msgNum = BaseDataInitialize.getMsgCount(1, Constant.IMAGE_TEXT_RULE_NUM_CODE);
//			TradeServiceInfo serviceInfo2 = tradeServiceInfoService.selectByPrimaryKey(info.getServiceType());
			LinkedHashMap<String,String> jsonMap =null;
/*			if(info.getServiceType()==ServiceTypeConstants.TEXT.getValue()){
				jsonMap =new LinkedHashMap<>();
				jsonMap.put("patientName", StringUtils.isBlank(patientCustomer.getName())?"有患者":patientCustomer.getName());
				jsonMap.put("serviceName", serviceInfo2.getName());
				jsonMap.put("hour", hourNum+"");
				jsonMap.put("msgNum", msgNum+"");
				AliSmsService.sendSMS(doctorInfo.getMobile(),jsonMap,AliSmsService.CREATE_ORDER_TEMPID);
			}else if(info.getServiceType()==ServiceTypeConstants.TEL.getValue()){
				CallPatient callPatient =new CallPatient();
				callPatient.setOrderNo(info.getOrderNo());
				CallPatientDto patientDto = patientBuyCallService.getCallPatientInfo(callPatient);
				//患者购买医生电话服务短信--患者端
				jsonMap =new LinkedHashMap<>();
				jsonMap.put("docName", doctorInfo.getName());
				AliSmsService.sendSMS(patientCustomer.getMobile(),jsonMap,AliSmsService.CREATE_TEL_ORDER_PATIENT);
				//患者购买医生电话服务短信--医生端
				jsonMap =new LinkedHashMap<>();
				jsonMap.put("patientName", patientDto.getPatientName());
				jsonMap.put("callTalkTime", info.getCallDuration()+"");
				AliSmsService.sendSMS(doctorInfo.getMobile(),jsonMap,AliSmsService.CREATE_TEL_ORDER_DOCTOR);
				
			}
			doctorInfoService.updateActiveTime(info.getDoctorId());*/
			return "success";

		} catch (AlipayApiException e) {
			e.printStackTrace();
			LOGGER.error("支付宝接口回调错误！");
		} catch (Exception e) {
			e.printStackTrace();
			LOGGER.error("支付宝接口系统错误！");
		}
		return "faild";
	}

	@Override
	public String refundRequest(TradeOrderInfo tradeOrderInfoTemp) {
		// 发送请求
		String strResponse = null;
		try {
			//订单号
			String out_trade_no = tradeOrderInfoTemp.getOrderNo();
			TradeOrderInfo info = tradeOrderInfoServiceImpl.selectByorderNo(out_trade_no);
			if (info == null) {
				LOGGER.debug("无法查询到订单查询信息！");
				return "faild";
			}
			AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.ALIPAY_URL, AlipayConfig.APP_ID,
					AlipayConfig.PRIVATE_KEY, AlipayConfig.CONTENT_TYPE, AlipayConfig.CHARSET, AlipayConfig.PUBLIC_KEY);
			AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
			AlipayRefundBizContent bizContent = new AlipayRefundBizContent();
			bizContent.setOut_trade_no(info.getOrderNo());
			bizContent.setRefund_amount(info.getOrderMoney());
			bizContent.setTrade_no(info.getPayOrderNo());
			request.setBizContent(JSONObject.toJSONString(bizContent));
			AlipayTradeRefundResponse response = alipayClient.execute(request);
			if (response == null) {
				LOGGER.debug("支付宝返回为空！");
				return "faild";
			}

			strResponse = response.getCode();
			if ("10000".equals(response.getCode())) {
				TradeOrderInfo tradeOrderInfo = new TradeOrderInfo();
				tradeOrderInfo.setOrderNo(out_trade_no);
				tradeOrderInfo.setRefundTime(response.getGmtRefundPay());// 退款时间
				tradeOrderInfo.setStatus(TradeOrderInfoStatus.ORDER_COMPLETE_REFUND.getValue());// 4已退款
				//退款理由
				if(StringUtils.isNotEmpty(tradeOrderInfoTemp.getRefundReason())){
					tradeOrderInfo.setRefundReason(tradeOrderInfoTemp.getRefundReason());
				}
				tradeOrderInfoServiceImpl.updateByPrimaryKeySelective(tradeOrderInfo);
				JedisManager.del(tradeOrderInfo.getOrderNo());
				strResponse = "success";
			} else {
				strResponse = response.getSubMsg();
			}
		} catch (Exception e) {
			LOGGER.error("支付宝退款接口出现异常！");
		}
		return strResponse;
	}

	// 回调
	@Override
	public String batchPaymentTheCallback(Map<String, String[]> requestParams) {
		try {

			// 获取支付宝POST过来反馈信息
			Map<String, String> params = new HashMap<String, String>();
			for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
				String name = (String) iter.next();
				String[] values = (String[]) requestParams.get(name);
				String valueStr = "";
				for (int i = 0; i < values.length; i++) {
					valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
				}
				// 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
				// valueStr = new String(valueStr.getBytes("ISO-8859-1"),
				// "gbk");
				params.put(name, valueStr);
			}

			if (AlipayNotify.verify(params)) { // 验证成功

				String[] param = params.get("success_details").split("\\|");// 拆分字符串
				for (String record : param) {
					String[] p = record.split("\\^");

					String cashNo = p[0];// 流水号
					String success = p[4];// 成功标识(S)
					String payTradeNo = p[6];// 支付宝内部流水号
					String endTime = p[7];// 完成时间
					// 商户需要验证该通知数据中的cashNo是否为商户系统中创建的提现流水号
//					TradeCashInfo info = tradeCashInfoService.getTradeCashInfo(cashNo);

		/*			if (info == null) {
						LOGGER.debug("支付宝回调cashNo校验失败！");
						return "fail";
					}

					if ("S".equals(success)) {
						info.setStatus(1);
					} else {
						info.setStatus(2);
					}*/

/*					SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
					Date endTime1 = sdf.parse(endTime);
					info.setEndTime(endTime1);// 时间
					info.setPayTradeNo(payTradeNo);*/
//					tradeCashInfoService.updateTradeCashInfo(info);
				}
				return "success"; // 请不要修改或删除
			}
			return "fail";

		} catch (Exception e) {
			e.printStackTrace();
			LOGGER.error("支付宝回调错误！");
		}
		return "fail";
	}

	@Override
	public Map<String, String> batchPayment(String cashNos) {
		Map<String, String> map = new HashMap<>();
		String batchNo = IdentityHelper.SerializeNo(); // 生成批次号
		StringBuffer sb = new StringBuffer();
		BigDecimal bd = new BigDecimal(0);
/*		tradeCashInfoService.batchUpdateTradeCashInfo(cashNos, batchNo);
		List<TradeCashInfo> infoList = tradeCashInfoService.findTradeCashInfoList(batchNo);
		if (CollectionUtils.isNotEmpty(infoList)) {
			int num = infoList.size();
			for (int i = 0; i < num; i++) {
				TradeCashInfo tr = infoList.get(i);
				sb.append(tr.getCashNo()).append("^").append(tr.getAccount()).append("^").append(tr.getAccountName())
						.append("^").append(tr.getCashMoney()).append("^")
						.append("好心情" + tr.getSettlementMonth() + "月份收益");
				bd = bd.add(tr.getCashMoney());
				if (i != num - 1) {
					sb.append("|");
				}
			}
			map.put("detailData", sb.toString());
			map.put("batchNo", batchNo);
			map.put("partner", AlipayConfig.PARTNER);
			map.put("inputCharset", AlipayConfig.INPUT_CHARSET);
			map.put("email", AlipayConfig.EMAIL);
			map.put("accountName", AlipayConfig.ACCOUNT_NAME);
			map.put("batchFee", bd.toString());
			map.put("batchNum", num + "");
		}*/
		return map;

	}
	
}
